#!/bin/bash

# Flink Web Analytics 项目同步脚本
# 用途：将本地代码同步到远程服务器

# 配置信息
REMOTE_USER="root"
REMOTE_HOST="10.1.1.69"
REMOTE_PATH="/home/yuncDataWorks/flink_web_analytics/"
LOCAL_PATH="$(cd "$(dirname "$0")" && pwd)/"

# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 显示横幅
echo -e "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║       Flink Web Analytics - 代码同步工具              ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
echo ""

# 显示同步信息
print_info "本地路径: ${LOCAL_PATH}"
print_info "远程服务器: ${REMOTE_USER}@${REMOTE_HOST}"
print_info "远程路径: ${REMOTE_PATH}"
echo ""

# 选择同步模式
print_warning "请选择同步模式："
echo -e "${GREEN}1)${NC} 完整同步（所有代码）${YELLOW}【推荐首次部署使用】${NC}"
echo -e "${GREEN}2)${NC} 模块同步（仅同步指定模块）${YELLOW}【适用于已完整部署后的增量更新】${NC}"
echo ""
read -p "$(echo -e ${YELLOW}请输入选项 [1-2]: ${NC})" sync_mode
echo ""

# 模块同步时的提醒
if [ "$sync_mode" = "2" ]; then
    print_warning "重要提示："
    echo "  • 模块同步适用于已完整部署的项目进行增量更新"
    echo "  • 如果是首次部署，建议使用【完整同步】模式"
    echo "  • 模块同步会覆盖基础文件（router/index.js等），请确保本地代码是完整的"
    echo ""
    read -p "$(echo -e ${YELLOW}确认继续模块同步？[y/N]: ${NC})" -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_warning "已取消，请选择完整同步"
        exit 0
    fi
    echo ""
    
    # 询问是否同步共享配置文件
    print_warning "是否同步共享配置文件？"
    echo "  • router/index.js (包含所有模块的路由配置)"
    echo "  • 如果你的本地路由配置是完整的，选择【是】"
    echo "  • 如果你只想同步模块文件，不影响路由配置，选择【否】"
    echo ""
    read -p "$(echo -e ${YELLOW}是否同步 router/index.js？[Y/n]: ${NC})" -n 1 -r
    echo ""
    SYNC_ROUTER="yes"
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        SYNC_ROUTER="no"
        print_info "将跳过 router/index.js 的同步"
    else
        print_info "将同步 router/index.js"
    fi
    echo ""
fi

# 定义同步文件列表
INCLUDE_FILES=""

# 基础模块（所有模块都依赖的文件）
BASE_FILES=(
    # 前端基础
    "frontend/src/main.js"
    "frontend/src/App.vue"
    "frontend/src/layout/"
    "frontend/src/utils/"
    "frontend/src/stores/app.js"
    "frontend/src/stores/menu.js"
    "frontend/src/stores/backgroundTask.js"
    "frontend/src/styles/"
    "frontend/src/components/"
    "frontend/package.json"
    "frontend/vite.config.js"
    # 后端基础
    "backend/run.py"
    "backend/app/__init__.py"
    "backend/app/config/"
    "backend/app/utils/logger.py"
    "backend/app/utils/mysql_db.py"
    "backend/app/utils/starrocks_db.py"
    "backend/config.env"
    "backend/requirements.txt"
)

# router/index.js 根据用户选择决定是否包含
if [ "$sync_mode" = "1" ] || [ "$SYNC_ROUTER" = "yes" ]; then
    BASE_FILES+=("frontend/src/router/index.js")
fi

if [ "$sync_mode" = "2" ]; then
    print_warning "请选择要同步的模块："
    echo -e "${GREEN} 1)${NC} Flink集群管理"
    echo -e "${GREEN} 2)${NC} 作业管理"
    echo -e "${GREEN} 3)${NC} 日志统计"
    echo -e "${GREEN} 4)${NC} 数据工具"
    echo -e "${GREEN} 5)${NC} Kafka监控管理"
    echo -e "${GREEN} 6)${NC} StarRocks表管理"
    echo -e "${GREEN} 7)${NC} 告警管理"
    echo -e "${GREEN} 8)${NC} Savepoint记录"
    echo -e "${GREEN} 9)${NC} JAR管理"
    echo -e "${GREEN}10)${NC} 三方配置"
    echo -e "${GREEN}11)${NC} StarRocks监控管理"
    echo ""
    read -p "$(echo -e ${YELLOW}请输入选项 [1-11]: ${NC})" module_choice
    echo ""

    case $module_choice in
        1)
            MODULE_NAME="Flink集群管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/FlinkCluster/"
                "frontend/src/stores/flinkEnv.js"
                # 后端文件
                "backend/app/blueprints/flink_cluster.py"
                "backend/app/blueprints/flink_monitor_config.py"
                "backend/app/utils/flink.py"
            )
            ;;
        2)
            MODULE_NAME="作业管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Jobs/"
                "frontend/src/stores/jobs.js"
                # 后端文件
                "backend/app/blueprints/jobs.py"
                "backend/app/utils/flink.py"
            )
            ;;
        3)
            MODULE_NAME="日志统计"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Logs/"
                # 后端文件
                "backend/app/blueprints/logs.py"
                "backend/app/services/log_service.py"
            )
            ;;
        4)
            MODULE_NAME="数据工具"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Tools/"
                # 后端文件
                "backend/app/blueprints/api_listener.py"
                "backend/app/blueprints/callback_enhanced.py"
                "backend/app/blueprints/kafka_forward.py"
                "backend/app/blueprints/kafka_monitor.py"
                "backend/app/blueprints/starrocks.py"
            )
            ;;
        5)
            MODULE_NAME="Kafka监控管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/KafkaMonitor/"
                "frontend/src/stores/kafkaMonitor.js"
                # 后端文件
                "backend/app/blueprints/kafka_monitor.py"
                "backend/app/blueprints/kafka_topic_monitor.py"
                "backend/app/utils/kafka_utils.py"
            )
            ;;
        6)
            MODULE_NAME="StarRocks表管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Tools/StarRocksTables/"
                # 后端文件
                "backend/app/blueprints/starrocks_tables.py"
                "backend/app/services/starrocks_service.py"
            )
            ;;
        7)
            MODULE_NAME="告警管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Alerts/"
                "frontend/src/stores/alerts.js"
                # 后端文件
                "backend/app/blueprints/alerts.py"
                "backend/app/blueprints/alerts_extended.py"
            )
            ;;
        8)
            MODULE_NAME="Savepoint记录"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Savepoints/"
                "frontend/src/stores/savepoints.js"
                # 后端文件
                "backend/app/blueprints/savepoints.py"
            )
            ;;
        9)
            MODULE_NAME="JAR管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Jars/"
                "frontend/src/stores/jars.js"
                # 后端文件
                "backend/app/blueprints/jars.py"
            )
            ;;
        10)
            MODULE_NAME="三方配置"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/Settings/"
                "frontend/src/stores/settings.js"
                # 后端文件
                "backend/app/blueprints/settings.py"
                "backend/app/blueprints/scheduler_management.py"
                "backend/app/services/scheduler_service.py"
                "backend/app/services/task_service.py"
            )
            ;;
        11)
            MODULE_NAME="StarRocks监控管理"
            MODULE_FILES=(
                # 前端文件
                "frontend/src/views/StarRocksMonitor/"
                # 后端文件
                "backend/app/blueprints/starrocks_cluster_monitor.py"
                "backend/app/services/starrocks_service.py"
            )
            ;;
        *)
            print_error "无效的选项"
            exit 1
            ;;
    esac

    # 合并基础文件和模块文件
    INCLUDE_FILES=("${BASE_FILES[@]}" "${MODULE_FILES[@]}")

    print_info "已选择模块: ${MODULE_NAME}"
    echo ""
    
    if [ "$SYNC_ROUTER" = "no" ]; then
        print_warning "注意: router/index.js 将不会被同步（保留远程现有配置）"
        echo ""
    fi
    
    print_info "将同步基础依赖文件 + 模块文件："
    echo -e "${YELLOW}[基础文件]${NC}"
    for file in "${BASE_FILES[@]}"; do
        [[ "$file" =~ ^#.* ]] && continue
        echo "  - ${file}"
    done
    echo ""
    echo -e "${YELLOW}[${MODULE_NAME} 模块文件]${NC}"
    for file in "${MODULE_FILES[@]}"; do
        [[ "$file" =~ ^#.* ]] && continue
        echo "  - ${file}"
    done
    echo ""
fi

# 确认同步
print_warning "即将开始同步，请确认以下信息："
if [ "$sync_mode" = "1" ]; then
    echo "  - 会同步所有源代码和配置文件"
else
    echo "  - 会同步基础依赖文件（前端框架、后端工具类等）"
    echo "  - 会同步 ${MODULE_NAME} 模块文件"
fi
echo "  - 会排除依赖包、编译产物、日志等"
echo ""
read -p "$(echo -e ${YELLOW}是否继续? [y/N]: ${NC})" -n 1 -r
echo ""

if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    print_warning "同步已取消"
    exit 0
fi

# 检查 SSH 密钥配置
print_info "检查 SSH 连接..."
ssh -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_USER}@${REMOTE_HOST}" exit 2>/dev/null
SSH_KEY_STATUS=$?

if [ $SSH_KEY_STATUS -ne 0 ]; then
    echo ""
    print_warning "检测到未配置 SSH 密钥认证，需要输入密码"
    print_info "为避免多次输入密码，建议配置 SSH 密钥："
    echo ""
    echo -e "${BLUE}配置步骤：${NC}"
    echo "  1. 生成密钥对：ssh-keygen -t rsa -b 4096"
    echo "  2. 复制公钥：ssh-copy-id ${REMOTE_USER}@${REMOTE_HOST}"
    echo "  3. 测试连接：ssh ${REMOTE_USER}@${REMOTE_HOST}"
    echo ""
    read -p "$(echo -e ${YELLOW}按回车键继续同步...${NC})"
    echo ""
fi

# 开始同步
print_info "开始同步代码..."
echo ""

# 执行 rsync 命令
if [ "$sync_mode" = "1" ]; then
    # 完整同步模式
    rsync -avz --progress \
      --exclude 'node_modules/' \
      --exclude 'venv/' \
      --exclude 'backend/venv/' \
      --exclude 'frontend/node_modules/' \
      --exclude 'frontend/dist/' \
      --exclude 'dist/' \
      --exclude 'build/' \
      --exclude '__pycache__/' \
      --exclude '*.pyc' \
      --exclude '*.pyo' \
      --exclude '.git/' \
      --exclude '.gitignore' \
      --exclude '.DS_Store' \
      --exclude 'logs/*.log' \
      --exclude 'logs/*.log.*' \
      --exclude 'logs/*.pid' \
      --exclude 'backend.pid' \
      --exclude 'frontend.pid' \
      --exclude '.vscode/' \
      --exclude '.idea/' \
      --exclude '*.swp' \
      --exclude '*.swo' \
      --exclude '.pytest_cache/' \
      --exclude '.coverage' \
      --exclude 'htmlcov/' \
      --exclude 'sync.sh' \
      "${LOCAL_PATH}" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}"
else
    # 模块同步模式 - 创建临时文件列表，一次性同步
    TEMP_FILE_LIST=$(mktemp)
    
    # 收集所有存在的文件和目录
    for file in "${INCLUDE_FILES[@]}"; do
        # 跳过注释行
        [[ "$file" =~ ^#.* ]] && continue
        
        if [ -e "${LOCAL_PATH}${file}" ]; then
            echo "${file}" >> "${TEMP_FILE_LIST}"
        else
            print_warning "文件不存在，跳过: ${file}"
        fi
    done
    
    # 使用单个 rsync 命令同步所有文件
    if [ -s "${TEMP_FILE_LIST}" ]; then
        print_info "准备同步 $(wc -l < ${TEMP_FILE_LIST} | tr -d ' ') 个文件/目录..."
        echo ""
        
        rsync -avzR --progress \
          --files-from="${TEMP_FILE_LIST}" \
          --exclude '__pycache__/' \
          --exclude '*.pyc' \
          --exclude '*.pyo' \
          --exclude '.DS_Store' \
          --exclude '*.swp' \
          --exclude '*.swo' \
          "${LOCAL_PATH}" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}"
        
        RSYNC_EXIT_CODE=$?
        rm -f "${TEMP_FILE_LIST}"
        
        if [ $RSYNC_EXIT_CODE -ne 0 ]; then
            print_error "同步失败"
            exit 1
        fi
    else
        print_error "没有找到可同步的文件"
        rm -f "${TEMP_FILE_LIST}"
        exit 1
    fi
fi

# 检查同步结果
if [ "$sync_mode" = "1" ]; then
    RSYNC_STATUS=$?
else
    RSYNC_STATUS=$RSYNC_EXIT_CODE
fi

if [ $RSYNC_STATUS -eq 0 ]; then
    echo ""
    print_success "代码同步完成！"
    echo ""
    print_info "后续步骤："
    echo "  1. SSH 登录到远程服务器: ssh ${REMOTE_USER}@${REMOTE_HOST}"
    echo "  2. 进入项目目录: cd ${REMOTE_PATH}"
    
    if [ "$sync_mode" = "2" ]; then
        echo "  3. 推荐部署方式（模块同步）："
        echo ""
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${GREEN}方式一：Docker 部署（推荐）${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  # 重新构建并启动（只重建受影响的服务）"
        echo "  docker-compose up -d --build"
        echo ""
        echo "  # 查看日志"
        echo "  docker-compose logs -f"
        echo ""
        
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${YELLOW}方式二：热重载（仅前端改动时）${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  # 前端重新编译"
        echo "  cd frontend && npm run build"
        echo ""
        
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${YELLOW}方式三：后端重启（仅后端改动时）${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  # 重启后端服务"
        echo "  cd backend && ./start.sh restart"
        echo ""
    else
        echo "  3. 选择部署方式："
        echo ""
        
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${GREEN}方式一：Docker 部署（推荐）${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  # 停止并删除旧容器"
        echo "  docker-compose down"
        echo ""
        echo "  # 重新构建并启动"
        echo "  docker-compose up -d --build"
        echo ""
        echo "  # 查看日志"
        echo "  docker-compose logs -f"
        echo ""
        
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${YELLOW}方式二：传统部署${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  ${GREEN}前端重新编译:${NC}"
        echo "  cd frontend && npm install && npm run build"
        echo ""
        echo "  ${GREEN}后端重启服务:${NC}"
        echo "  cd backend && ./start.sh restart"
        echo ""
        
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${YELLOW}快速命令（二选一）:${NC}"
        echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo "  ${GREEN}Docker:${NC}  docker-compose down && docker-compose up -d --build"
        echo "  ${GREEN}传统:${NC}    ./deploy.sh"
        echo ""
    fi
else
    echo ""
    print_error "同步失败，请检查网络连接和服务器配置"
    exit 1
fi

